/*
 * =====================================================================================
 *
 *       Filename:  cl_event_looper.hxx
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  04/07/2011 09:17:02 AM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Ken Chen (Ken), chen_kenz@emc.com
 *        Company:  EMC
 *
 * =====================================================================================
 */

#ifndef _CL_EVENT_LOOPER_HXX_
#define _CL_EVENT_LOOPER_HXX_

#include <cassert>
#include <vector>
#include <memory>
#include <atomic>
#include "cl_callback.hxx"
#include "cl_thread.hxx"

namespace neo
{
class CLId;
class CLLock;
class CLPoller;
class CLThread;
class CLChannel;
class CLTimestamp;
class CLTimerService;

// Handle event handlers in a seperate thread.
class CLEventLooper
{
public:
  CLEventLooper();
  ~CLEventLooper();
  void start(void); 
  bool addChannel(CLChannel* ch);
  bool removeChannel(CLChannel* ch);
  bool modifyChannel(CLChannel* ch);
  void shutdown(void);
  void queueJob(const CLCallbackFunctor& cb);
  void runJob(const CLCallbackFunctor& cb);
	// interact with Timer service
  const CLId runJobAt(const CLTimestamp& atTime, const CLCallbackFunctor& timerCallback);
  const CLId runJobAfter(int msecsDelay, const CLCallbackFunctor& timerCallback);
	const CLId runJobEvery(int msecInterval, const CLCallbackFunctor& timerCallback);
  void cancelTimerJob(const CLId& timerId);

	bool isInLooperThread(void) const
	{
    return m_thr->isCurThread();
	}

	void assertInLoopThread(void) 
	{
    if(!isInLooperThread())
		{
			assert(0);
		}
	}

private:
  void loop(void);
  void wakeup(void);
  void handleRead(void);
  void doPendingJobs(void);
	int nextPollInterval(void) const;

private:
  CLEventLooper(const CLEventLooper&);
  CLEventLooper& operator=(const CLEventLooper&);

private:
  typedef std::vector<CLCallbackFunctor> CallbackVector;

private:
  int m_eventfd;
  std::atomic<bool> m_shutdown;
  std::unique_ptr<CLLock> m_lock;
  std::unique_ptr<CLPoller> m_poller;
  std::unique_ptr<CLChannel> m_eventChannel; 
	std::unique_ptr<CLTimerService> m_timerService;
  std::unique_ptr<CLThread> m_thr;
  CallbackVector m_callbacks;
};
} // neo

#endif //_CL_EVENT_LOOPER_H_ 

